﻿using Abp.Application.Services.Dto;
using Abp.Auditing;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using Abp.UI;
using FutureApp.Shop.Dto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace FutureApp.Shop
{
    /// <AppService/>
    [DisableAuditing]
    public class GoodsCategoryAppService : FutureAppAppServiceBase, IGoodsCategoryAppService
    {
        private IRepository<GoodsCategory, Guid> GoodsCategoryRepository { get; }
        private IRepository<GoodsCategoryAssemble, Guid> GoodsCategoryAssembleRepository { get; }

        /// <constructor/>
        public GoodsCategoryAppService(
            IRepository<GoodsCategory, Guid> goodsCategoryRepository,
            IRepository<GoodsCategoryAssemble, Guid> goodsCategoryAssembleRepository
        )
        {
            this.GoodsCategoryRepository = goodsCategoryRepository;
            this.GoodsCategoryAssembleRepository = goodsCategoryAssembleRepository;
        }
        
        /// <inheritDoc/>
        public async Task<ListResultDto<GoodsCategoryEntityDto>> GetGoodsCategoryList()
        {
            var list = await this.GoodsCategoryRepository.GetAllListAsync();
            return new ListResultDto<GoodsCategoryEntityDto>(
                list.MapTo<List<GoodsCategoryEntityDto>>()
                );
        }

        /// <inheritDoc/>
        public async Task<GoodsCategoryEntityDto> GetGoodsCategory(Guid id)
        {
            if (!await this.ExistGoodsCategory(id))
                throw new UserFriendlyException(L("NotExistedGoodsCategory"));
            var entity = await this.GoodsCategoryRepository.GetAsync(id);
            return entity.MapTo<GoodsCategoryEntityDto>();
        }

        /// <inheritDoc/>
        public async Task<GoodsCategoryEntityDto> GetGoodsCategory(string name)
        {
            if (!await this.ExistGoodsCategory(name))
                throw new UserFriendlyException(L("NotExistedGoodsCategory"));
            var entity = await this.GoodsCategoryRepository.FirstOrDefaultAsync(e => e.Name == name);
            return entity.MapTo<GoodsCategoryEntityDto>();
        }

        /// <inheritDoc/>
        public async Task<bool> ExistGoodsCategory(Guid id)
        {
            var count = await this.GoodsCategoryRepository.CountAsync(e => e.Id == id);
            return count != 0;
        }

        /// <inheritDoc/>
        public async Task<bool> ExistGoodsCategory(string name)
        {
            var count = await this.GoodsCategoryRepository.CountAsync(e => e.Name == name);
            return count != 0;
        }

        /// <inheritDoc/>
        public async Task CreateGoodsCategory(CreateGoodsCategoryInput input)
        {
            if (await this.ExistGoodsCategory(input.Name))
                throw new UserFriendlyException(L("ExistedGoodsCategoryName"));

            var entity = input.MapTo<GoodsCategory>();
            entity = await this.GoodsCategoryRepository.InsertAsync(entity);
            input.GoodsProperties?.Select(val => new GoodsCategoryAssemble { CategoryId = entity.Id, PropertyId = val })
                .ToList().ForEach(e => this.GoodsCategoryAssembleRepository.InsertAsync(e));
        }

        /// <inheritDoc/>
        public async Task AssembleGoodsCategory(AssembleGoodsCategoryInput input)
        {
            if (!await this.ExistGoodsCategory(input.GoodsCategory))
                throw new UserFriendlyException(L("NotExistedGoodsCategory"));
            await this.GoodsCategoryAssembleRepository.DeleteAsync(e => e.CategoryId == input.GoodsCategory);
            input.GoodsProperties?.Select(val => new GoodsCategoryAssemble { CategoryId = input.GoodsCategory, PropertyId = val })
                .ToList().ForEach(e => this.GoodsCategoryAssembleRepository.InsertAsync(e));
        }

        /// <inheritDoc/>
        public async Task EnableGoodsCategory(Guid id)
        {
            if (!await this.ExistGoodsCategory(id))
                throw new UserFriendlyException(L("NotExistedGoodsCategory"));
            var e = await this.GoodsCategoryRepository.GetAsync(id);
            e.IsActive = true;
        }

        /// <inheritDoc/>
        public async Task DisableGoodsCategory(Guid id)
        {
            if (!await this.ExistGoodsCategory(id))
                throw new UserFriendlyException(L("NotExistedGoodsCategory"));
            var e = await this.GoodsCategoryRepository.GetAsync(id);
            e.IsActive = false;
        }
    }
}
